Coverage Report

Created: 2021-08-28 18:14

D:\git\skunkworks\herald-for-cpp\herald\src\datatype\distribution.cpp
Line
Count
Source (jump to first uncovered line)
1
//  Copyright 2021 Herald Project Contributors
2
//  SPDX-License-Identifier: Apache-2.0
3
//
4
5
#include "herald/datatype/distribution.h"
6
7
#include <limits>
8
#include <cmath>
9
10
namespace herald {
11
namespace datatype {
12
13
Distribution::Distribution() noexcept
14
  : n(0),
15
    m1(0.0),
16
    m2(0.0),
17
    minimum(std::numeric_limits<double>::max()),
18
    maximum(std::numeric_limits<double>::min())
19
9
{
20
9
  ;
21
9
}
22
23
Distribution::Distribution(double x, std::size_t frequency) noexcept
24
  : n(frequency),
25
    m1(x),
26
    m2(0),
27
    minimum(x),
28
    maximum(x)
29
1
{
30
1
  ;
31
1
}
32
33
void
34
Distribution::add(double x) noexcept
35
23
{
36
23
  // Update count, mean, variance
37
23
  std::size_t n1 = n;
38
23
  ++n;
39
23
  double delta = x - m1;
40
23
  double delta_n = delta / n;
41
23
  double term1 = delta * delta_n * n1;
42
23
  m1 += delta_n;
43
23
  m2 += term1;
44
23
  // update min, max
45
23
  if (x < minimum) {
46
7
    minimum = x;
47
7
  }
48
23
  if (x > maximum) {
49
22
    maximum = x;
50
22
  }
51
23
}
52
53
void
54
Distribution::add(double x, std::size_t frequency) noexcept
55
0
{
56
0
  for (std::size_t i = 0;i < frequency;++i) {
57
0
    add(x);
58
0
  }
59
0
}
60
61
void
62
Distribution::add(const Distribution& other) noexcept
63
1
{
64
1
  if (0 == n) {
65
0
    n = other.n;
66
0
    m1 = other.m1;
67
0
    m2 = other.m2;
68
0
    minimum = other.minimum;
69
0
    maximum = other.maximum;
70
0
    return;
71
0
  }
72
1
  // Combine distribution if this distribution is not empty
73
1
  std::size_t new_n = n + other.n;
74
1
75
1
  double delta = other.m1 - m1;
76
1
  double delta2 = delta * delta;
77
1
78
1
  m1 = ((n * m1) + (other.n * other.m1)) / new_n;
79
1
  m2 = m2 + other.m2 + ((delta2 * n * other.n) / new_n);
80
1
  
81
1
  // set values
82
1
  n = new_n;
83
1
  minimum = minimum < other.minimum ? minimum : 
other.minimum0
;
84
1
  maximum = maximum > other.maximum ? 
maximum0
: other.maximum;
85
1
}
86
87
const std::size_t
88
Distribution::count() const noexcept
89
10
{
90
10
  return n;
91
10
}
92
93
const double
94
Distribution::mean() const noexcept
95
20
{
96
20
  return m1;
97
20
}
98
99
const double
100
Distribution::variance() const noexcept
101
14
{
102
14
  if (n < 2) { // guard
103
3
    return 0;
104
3
  }
105
11
  return m2 / (n - 1);
106
11
}
107
108
const double
109
Distribution::standardDeviation() const noexcept
110
9
{
111
9
  if (n < 2) { // guard
112
3
    return 0;
113
3
  }
114
6
  return std::sqrt(variance());
115
6
}
116
117
const double
118
Distribution::min() const noexcept
119
10
{
120
10
  return minimum;
121
10
}
122
123
const double
124
Distribution::max() const noexcept
125
10
{
126
10
  return maximum;
127
10
}
128
129
Distribution::operator std::string() const noexcept
130
1
{
131
1
  return "[count=" + std::to_string(count()) + ",mean=" + std::to_string(mean()) + 
132
1
         ",sd=" + std::to_string(standardDeviation()) + ",min=" + std::to_string(min()) +
133
1
         ",max=" + std::to_string(max()) + "]";
134
1
}
135
136
void
137
Distribution::reset() noexcept
138
2
{
139
2
  n = 0;
140
2
  m1 = 0.0;
141
2
  m2 = 0.0;
142
2
  minimum = std::numeric_limits<double>::max();
143
2
  maximum = std::numeric_limits<double>::min();
144
2
}
145
146
}
147
}